﻿using System;
using System.Configuration;

namespace smp.QueryDb
{
    public class DbSessionFactory : IDbSessionFactory
    {
        private readonly ConnectionStringSettings _connectionStringSettings;
        private readonly IDbAdapter _adapter;
        private readonly ILog _log;

        public DbSessionFactory(string connectionStringKey)
        {
            if (string.IsNullOrEmpty(connectionStringKey))
            {
                throw Helper.LogException(new ArgumentNullException(connectionStringKey));
            }
            
            var connectionStringSettings = ConfigurationManager.ConnectionStrings[connectionStringKey];
            if (connectionStringSettings == null)
            {
                throw Helper.LogException(new ConfigurationErrorsException("Missing or invalid connection string in configuration for key : " + connectionStringKey));
            }

            var adapter = InstanceFactory.GetAdapter(connectionStringSettings.ProviderName);
            _connectionStringSettings = connectionStringSettings;
            _adapter = adapter;
            _log = new DebugLog();
        }

        public DbSessionFactory(string connectionStringKey, IDbAdapter adapter)
        {
            if (string.IsNullOrEmpty(connectionStringKey))
            {
                throw Helper.LogException(new ArgumentNullException(connectionStringKey));
            }
            
            var connectionStringSettings = ConfigurationManager.ConnectionStrings[connectionStringKey];
            if (connectionStringSettings == null)
            {
                throw Helper.LogException(new ConfigurationErrorsException("Missing or invalid connection string in configuration for key : " + connectionStringKey));
            }

            _connectionStringSettings = connectionStringSettings;
            _adapter = adapter;
            _log = new DebugLog();
        }

        public DbSessionFactory(string connectionStringKey, IDbAdapter adapter, ILog log)
        {
            if (string.IsNullOrEmpty(connectionStringKey))
            {
                throw Helper.LogException(new ArgumentNullException(connectionStringKey));
            }
            
            var connectionStringSettings = ConfigurationManager.ConnectionStrings[connectionStringKey];
            if (connectionStringSettings == null)
            {
                throw Helper.LogException(new ConfigurationErrorsException("Missing or invalid connection string in configuration for key : " + connectionStringKey));
            }

            _connectionStringSettings = connectionStringSettings;
            _adapter = adapter;
            _log = log;
        }

        public DbSessionFactory(ConnectionStringSettings connectionStringSettings)
        {
            var adapter = InstanceFactory.GetAdapter(connectionStringSettings.ProviderName);
            _connectionStringSettings = connectionStringSettings;
            _adapter = adapter;
            _log = new DebugLog();
        }

        public DbSessionFactory(ConnectionStringSettings connectionStringSettings, ILog log)
        {
            var adapter = InstanceFactory.GetAdapter(connectionStringSettings.ProviderName);
            _connectionStringSettings = connectionStringSettings;
            _adapter = adapter;
            _log = log;
        }

        public DbSessionFactory(ConnectionStringSettings connectionStringSettings, IDbAdapter adapter)
        {
            _connectionStringSettings = connectionStringSettings;
            _adapter = adapter;
            _log = new DebugLog();
        }

        public DbSessionFactory(ConnectionStringSettings connectionStringSettings, IDbAdapter adapter, ILog log)
        {
            _connectionStringSettings = connectionStringSettings;
            _adapter = adapter;
            _log = log;
        }

        #region Implementation of IDbSessionFactory

        public IDbSession Create()
        {
            return new DbSession(_connectionStringSettings, _adapter, _log);
        }

        public IDbSession Create(bool startTransaction)
        {
            var session = new DbSession(_connectionStringSettings, _adapter, _log);
            session.StartTransaction();
            return session;
        }

        #endregion
    }
}
